package com.qdone.module.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.qdone.framework.error.ExceptionUtil;
import com.qdone.framework.error.RRException;
import com.qdone.module.model.Student;
import com.qdone.module.service.StudentService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;

/**
 * Sentinel限流器使用
 * 1.本地可以配置熔断处理方法，以及熔断规则
 * 2.可以在dashboard动态配置熔断规则，配置成功之后本地运行即可生效，
 *   只是此时路由规则配置在内存中（本地如果重启，远程配置会出现问题），需要配置到nacos持久化
 * 3.熔断方法可以在参考sayHello方法这种，直接指定默认熔断，特定熔断方法处理
 * 4.熔断方法也可以指定通用的熔断处理方法，例如:
 *
 *
 * 5.参考资料
 *   https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
 *   https://github.com/alibaba/Sentinel/blob/master/sentinel-extension/sentinel-annotation-aspectj/README.md
 *   https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestServiceImpl.java
 */
@Controller
@RequestMapping("/boot")
@RefreshScope
public class SentinelController {

	/**
	 * Sentinel限流配置:
	 *   https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
	 *   https://github.com/alibaba/Sentinel/blob/master/sentinel-extension/sentinel-annotation-aspectj/README.md
	 *   https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestServiceImpl.java
	 * sayHello方法简单配置熔断异常
	 */
	@RequestMapping(value = "/sayHello", method =RequestMethod.GET)
	@ResponseBody
	@SentinelResource(value = "sayHello",fallback = "doFallback",defaultFallback = "defaultFallback")
	public String sayHello(String name) {
		if(StringUtils.isEmpty(name)){
			throw new RRException("用户名称不能为空!", HttpStatus.INTERNAL_SERVER_ERROR.value());
		}
		return "Hello, " + name;
	}


	/**
	 * Sentinel限流配置:
	 *   https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
	 *   https://github.com/alibaba/Sentinel/blob/master/sentinel-extension/sentinel-annotation-aspectj/README.md
	 *   https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-annotation-spring-aop/src/main/java/com/alibaba/csp/sentinel/demo/annotation/aop/service/TestServiceImpl.java
	 * speakHello方法简单配置通用阻塞熔断异常
	 */
	@RequestMapping(value = "/speakHello", method =RequestMethod.GET)
	@ResponseBody
	@SentinelResource(value = "speakHello",blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
	public String speakHello(String name) {
		if(StringUtils.isEmpty(name)){
			throw new RRException("用户名称不能为空!", HttpStatus.INTERNAL_SERVER_ERROR.value());
		}
		return "Hello, " + name;
	}



	/**
	 * Sentinel限流配置:
	 *   https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
	 */
	public String doFallback(String name, Throwable t) {
		// Return fallback value.
		System.err.println("我是指定的熔断器，异常信息是:"+t.getMessage());
		t.printStackTrace();
		return "fallback:"+name;
	}
	/**
	 * Sentinel限流配置:
	 *   https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
	 */
	public String defaultFallback(Throwable t) {
		System.err.println("我是默认的熔断器,异常信息是:"+t.getMessage());
		return "default_fallback";
	}
}